# NumPy 中还可以使用高级索引方式，比如整数数组索引、布尔索引以及花式索引
# 高级索引返回的是数组的副本（深拷贝），而切片操作返回的是数组视图（浅拷贝）
import numpy as np

# 整数数组索引

# 创建二维数组
x = np.array([[1, 2], [3, 4], [5, 6]])
# [0,1,2]代表行索引;[0,1,0]代表列索引
y = x[[0, 1, 2], [0, 1, 0]]  # 相当于X00,X11,X20
print(y)  # [1  4  5]

b = np.array([[0, 1, 2],
              [3, 4, 5],
              [6, 7, 8],
              [9, 10, 11]])
r = np.array([[0, 0], [3, 3]])
c = np.array([[0, 2], [0, 2]])
# 获取四个角的元素
d = b[r, c]  # 数组放进数组中就表示成索引
print(b)  # [[ 0  1  2] [ 3  4  5] [ 6  7  8] [ 9 10 11]]
print(r)  # [[0 0] [3 3]]
print(c)  # [[0 2] [0 2]]
print(d)  # [[ 0  2] [ 9 11]]

d = np.array([[0, 1, 2],
              [3, 4, 5],
              [6, 7, 8],
              [9, 10, 11]])
# 对行列分别进行切片
e = d[1:4, 1:3]
print(e)  # [[ 4  5][ 7  8][10 11]]
# 行使用基础索引，对列使用高级索引
f = d[1:4, [1, 2]]  # 第1行-第4行， 第1列-第2列
# 显示切片后结果
print(f)  # [[ 4  5][ 7  8][10 11]]
# 对行使用省略号
h = d[..., 1:]
print(h)  # [[ 1,  2], [ 4,  5], [ 7,  8], [10, 11]]

# 布尔数组索引

# 返回所有大于6的数字组成的数组
x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
print(x[x > 6])  # [ 7  8  9 10 11]

# 我们可以使用补码运算符来去除 NaN（即非数字元素）
a = np.array([np.nan, 1, 2, np.nan, 3, 4, 5])
print(a[~np.isnan(a)])  # [ 1.   2.   3.   4.   5.]

# 删除数组中整数元素
a = np.array([1, 2 + 6j, 5, 3.5 + 5j])
print(a[np.iscomplex(a)])  # [2.0+6.j  3.5+5.j]

# 花式索引

# 如果原数组是二维数组，那么索引数组也需要是二维的，索引数组的元素值与被索引数组的每一行相对应
x = np.arange(32).reshape((8, 4))
print(x[[4, 2, 1, 7]])  # 分别对应 第4行数据、第2行数据、第1行数据、第7行数据项
# [[16 17 18 19]
# [ 8  9 10 11]
# [ 4  5  6  7]
# [28 29 30 31]]
print(x[[-4, -2, -1, -7]])  # 也可以使用倒序索引数组
# [[16 17 18 19]
# [24 25 26 27]
# [28 29 30 31]
# [ 4  5  6  7]]

# 还可以同时使用多个索引数组，但这种情况下需要添加np.ix_。
# 其中 [1,5,7,2] 代表行索引，而 [0,3,1,2] 表示与行索引相对应的列索引值，也就是行中的元素值会按照列索引值排序。
# 比如，第一行元素，未排序前的顺序是 [4,5,6,7]，经过列索引排序后变成了 [4,7,5,6]。
print(x[np.ix_([1, 5, 7, 2], [0, 3, 1, 2])])
# [[ 4  7  5  6]
# [20 23 21 22]
# [28 31 29 30]
# [ 8 11  9 10]]
